package com.huanuo.internetofthings.service.impact.statistics;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.unicorn.framework.core.ResponseDto;
import org.unicorn.framework.core.exception.PendingException;

import com.huanuo.internetofthings.bo.impact.ImpactMonthStatistics;
import com.huanuo.internetofthings.bo.user.UserInfo;
import com.huanuo.internetofthings.dto.impact.ImpactDeviceStatisticsReqDto;
import com.huanuo.internetofthings.enums.ImpactDeviceStatisticsType;

/**
 * 设备开工率环比增长率分布
 * 
 * @author xiebin
 *
 */
@Service
public class ImpactDeviceCommencementRingRateStatisticsService extends AbstractImpactDeviceStatisticsService {

	@Override
	public ImpactMonthStatistics getImpactMonthStatistics(UserInfo userInfo) throws PendingException {
		int year = getYear();
		return getImpactMonthStatistics(year,null,userInfo.getGroupNo());
	}

	 /**
     * 获取ImpactMonthStatistics
     * @param year
     * @param groupNo
     * @return
     * @throws PendingException
     */
	private ImpactMonthStatistics getImpactMonthStatistics(Integer year,Integer month,String groupNo) throws PendingException{
		ImpactMonthStatistics impactMonthStatistics = new ImpactMonthStatistics();
		impactMonthStatistics.setGroupNo(groupNo);
		impactMonthStatistics.setYear(year);
		impactMonthStatistics.setMonth(month);
		return impactMonthStatistics;
	}
	
	private Map<Integer, Double> calculationRingRatio(Map<Integer, BigDecimal> thisPeriodMap, String groupNo)
			throws PendingException {
		Map<Integer, Double> returnMap = getSortMap(Double.class);
		BigDecimal fristMonthRate = thisPeriodMap.get(1);
		Set<Integer> monthSet = thisPeriodMap.keySet();
		for (Integer m : monthSet) {
			Integer mm = (m - 1) % 12;
			Double rate = 0d;
			if (mm != 0) {
				BigDecimal last = thisPeriodMap.get(mm);
				BigDecimal current = thisPeriodMap.get(m);
				BigDecimal subtract = (current.subtract(last)).multiply(new BigDecimal(100));
				BigDecimal divide = subtract.divide(last, 2, BigDecimal.ROUND_HALF_UP);
				// 其他月份last
				rate = divide.doubleValue();
			}
			returnMap.put(m, rate);
		}
		// 一月份
		returnMap.put(1, calculationFristMonthRingRatio(fristMonthRate, groupNo));
		return returnMap;
	}
	
	private Double calculationFristMonthRingRatio(BigDecimal fristMonthRate, String groupNo) throws PendingException {
		int year = getYear();
		ImpactMonthStatistics impactMonthStatistics= getImpactMonthStatistics(year - 1,12,groupNo);
		// 根据用户所属组查询上一年12月份汇总信息
		List<ImpactMonthStatistics> impactMonthStatisticsList = impactDeviceMonthStatisticsService
				.getImpactMonthStatisticsList(impactMonthStatistics);
		Integer deviceTotal = impactMonthStatisticsList.stream().mapToInt(ImpactMonthStatistics::getDeviceTotal)
				.sum();
		Integer commencementTotal = impactMonthStatisticsList.stream()
				.mapToInt(ImpactMonthStatistics::getCommencementTotal).sum();
		//计算上一年12月份开工率
		BigDecimal lastMonthRate = new BigDecimal(commencementTotal).multiply(new BigDecimal(100))
				.divide(new BigDecimal(deviceTotal),2, BigDecimal.ROUND_HALF_UP);
		return (fristMonthRate.subtract(lastMonthRate)).multiply(new BigDecimal(100)).divide(lastMonthRate,2, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	@Override
	public ResponseDto<?> calculationStatistics(List<ImpactMonthStatistics> impactMonthStatisticsList,UserInfo userInfo)
			throws PendingException {
		// 按月分组
		Map<Integer, List<ImpactMonthStatistics>> mapGroupbyMonth = impactMonthStatisticsList.stream()
				.collect(Collectors.groupingBy(ImpactMonthStatistics::getMonth));
        //初始化统计结果
		Map<Integer, BigDecimal> thisPeriodMap = getSortMap(BigDecimal.class);
		for (int m = 1; m <= 12; m++) {
			thisPeriodMap.put(m, new BigDecimal(0));
		}
		Set<Integer> set = mapGroupbyMonth.keySet();
		for (Integer mm : set) {
			Integer deviceTotal = mapGroupbyMonth.get(mm).stream().mapToInt(ImpactMonthStatistics::getDeviceTotal)
					.sum();
			Integer commencementTotal = impactMonthStatisticsList.stream()
					.mapToInt(ImpactMonthStatistics::getCommencementTotal).sum();
			BigDecimal rate = new BigDecimal(commencementTotal).multiply(new BigDecimal(100))
					.divide(new BigDecimal(deviceTotal),2, BigDecimal.ROUND_HALF_UP);
			thisPeriodMap.put(mm, rate);
		}
		Map<Integer, Double> returnMap = calculationRingRatio(thisPeriodMap, userInfo.getGroupNo());
		return new ResponseDto<>(returnMap);
	}


	@Override
	public boolean supports(ImpactDeviceStatisticsReqDto s) throws PendingException {
		return ImpactDeviceStatisticsType.Month_CommencementRingRateDistribution.equals(s.getImpactDeviceStatisticsType());
	}

}